package com.define.commons.common.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.Set;

/**
 * 默认值序列化操作类
 * ArrayList List Set 为 null 序列化为 []
 * @Author xiewenlong
 * @Date 2018/12/14 14:27
 */
@Component
public class DefaultValueSerializerModifier extends BeanSerializerModifier {

    private JsonSerializer nullArrayJsonSerializer = new NullArrayJsonSerializer();

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
        //循环所有的beanPropertyWriter
        for (int i = 0; i < beanProperties.size(); i++) {
            BeanPropertyWriter writer = beanProperties.get(i);
            /**
             * 判断字段的类型，如果是 ArrayList List Set 序列化为 []
             */
            if (isArrayType(writer)) {
                writer.assignNullSerializer(nullArrayJsonSerializer);
            }
        }
        return beanProperties;
    }

    /**
     * 是数组类型
     */
    public boolean isArrayType(BeanPropertyWriter writer) {
        Class clazz = writer.getPropertyType();
        return clazz.isArray() || clazz.equals(List.class) || clazz.equals(Set.class);
    }

}

class NullArrayJsonSerializer extends JsonSerializer{
    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException, JsonProcessingException {
        if(value ==null) {
            gen.writeStartArray();
            gen.writeEndArray();
        }else {
            gen.writeObject(value);
        }
    }
}
